/*
 * PCB elegance (Open source tools for making printed circuit boards)
 *
 * Copyright (C) 2012  Herman Morsink Vollenbroek
 *
 * File: calcdef.c
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*******************************************************************************************/


#include "types.h"
#include "calcdef.h"
#include "calc3.h"
#include "string.h"
#include "math.h"
#include "stdio.h"
#include "memory.h"
#include "graphics.h"
#include "files2.h"
#include "utf8.h"
#include "uservar.h"
#include "time.h"
#include "ctype.h"

extern int32 DrawWindowMinX, DrawWindowMinY, DrawWindowMaxX, DrawWindowMaxY;

int32 TempUnits;
char ConvertedTextString[MAX_LENGTH_STRING];

double CircleSin[257] = { 0.00000000000000, 0.04906767432742, 0.09801714032956, 0.14673047445536,
                          0.19509032201613, 0.24298017990326, 0.29028467725446, 0.33688985339222,
                          0.38268343236509, 0.42755509343028, 0.47139673682600, 0.51410274419322,
                          0.55557023301960, 0.59569930449243, 0.63439328416365, 0.67155895484702,
                          0.70710678118655, 0.74095112535496, 0.77301045336274, 0.80320753148064,
                          0.83146961230255, 0.85772861000027, 0.88192126434835, 0.90398929312344,
                          0.92387953251129, 0.94154406518302, 0.95694033573221, 0.97003125319454,
                          0.98078528040323, 0.98917650996478, 0.99518472667220, 0.99879545620517,
                          1.00000000000000, 0.99879545620517, 0.99518472667220, 0.98917650996478,
                          0.98078528040323, 0.97003125319454, 0.95694033573221, 0.94154406518302,
                          0.92387953251129, 0.90398929312344, 0.88192126434836, 0.85772861000027,
                          0.83146961230255, 0.80320753148065, 0.77301045336274, 0.74095112535496,
                          0.70710678118655, 0.67155895484702, 0.63439328416365, 0.59569930449243,
                          0.55557023301960, 0.51410274419322, 0.47139673682600, 0.42755509343028,
                          0.38268343236509, 0.33688985339222, 0.29028467725446, 0.24298017990326,
                          0.19509032201613, 0.14673047445536, 0.09801714032956, 0.04906767432742,
                          0.00000000000000, -0.04906767432742, -0.09801714032956, -0.14673047445536,
                          -0.19509032201613, -0.24298017990326, -0.29028467725446, -0.33688985339222,
                          -0.38268343236509, -0.42755509343028, -0.47139673682600, -0.51410274419322,
                          -0.55557023301960, -0.59569930449243, -0.63439328416364, -0.67155895484702,
                          -0.70710678118655, -0.74095112535496, -0.77301045336274, -0.80320753148064,
                          -0.83146961230254, -0.85772861000027, -0.88192126434835, -0.90398929312344,
                          -0.92387953251129, -0.94154406518302, -0.95694033573221, -0.97003125319454,
                          -0.98078528040323, -0.98917650996478, -0.99518472667220, -0.99879545620517,
                          -1.00000000000000, -0.99879545620517, -0.99518472667220, -0.98917650996478,
                          -0.98078528040323, -0.97003125319454, -0.95694033573221, -0.94154406518302,
                          -0.92387953251129, -0.90398929312344, -0.88192126434836, -0.85772861000027,
                          -0.83146961230255, -0.80320753148065, -0.77301045336274, -0.74095112535496,
                          -0.70710678118655, -0.67155895484702, -0.63439328416365, -0.59569930449243,
                          -0.55557023301960, -0.51410274419322, -0.47139673682600, -0.42755509343028,
                          -0.38268343236509, -0.33688985339222, -0.29028467725446, -0.24298017990327,
                          -0.19509032201613, -0.14673047445536, -0.09801714032956, -0.04906767432742,
                          0.00000000000000, 0.04906767432742, 0.09801714032956, 0.14673047445536,
                          0.19509032201613, 0.24298017990326, 0.29028467725446, 0.33688985339222,
                          0.38268343236509, 0.42755509343028, 0.47139673682600, 0.51410274419322,
                          0.55557023301960, 0.59569930449243, 0.63439328416364, 0.67155895484702,
                          0.70710678118655, 0.74095112535496, 0.77301045336274, 0.80320753148064,
                          0.83146961230254, 0.85772861000027, 0.88192126434835, 0.90398929312344,
                          0.92387953251129, 0.94154406518302, 0.95694033573221, 0.97003125319454,
                          0.98078528040323, 0.98917650996478, 0.99518472667220, 0.99879545620517,
                          1.00000000000000, 0.99879545620517, 0.99518472667220, 0.98917650996478,
                          0.98078528040323, 0.97003125319454, 0.95694033573221, 0.94154406518302,
                          0.92387953251129, 0.90398929312344, 0.88192126434836, 0.85772861000027,
                          0.83146961230255, 0.80320753148065, 0.77301045336274, 0.74095112535496,
                          0.70710678118655, 0.67155895484702, 0.63439328416365, 0.59569930449243,
                          0.55557023301960, 0.51410274419322, 0.47139673682600, 0.42755509343028,
                          0.38268343236509, 0.33688985339222, 0.29028467725446, 0.24298017990327,
                          0.19509032201613, 0.14673047445536, 0.09801714032956, 0.04906767432742,
                          0.00000000000000, -0.04906767432742, -0.09801714032956, -0.14673047445536,
                          -0.19509032201613, -0.24298017990326, -0.29028467725446, -0.33688985339222,
                          -0.38268343236509, -0.42755509343028, -0.47139673682600, -0.51410274419322,
                          -0.55557023301960, -0.59569930449243, -0.63439328416364, -0.67155895484702,
                          -0.70710678118655, -0.74095112535496, -0.77301045336274, -0.80320753148064,
                          -0.83146961230254, -0.85772861000027, -0.88192126434835, -0.90398929312344,
                          -0.92387953251129, -0.94154406518302, -0.95694033573221, -0.97003125319454,
                          -0.98078528040323, -0.98917650996478, -0.99518472667220, -0.99879545620517,
                          -1.00000000000000, -0.99879545620517, -0.99518472667220, -0.98917650996478,
                          -0.98078528040323, -0.97003125319454, -0.95694033573221, -0.94154406518302,
                          -0.92387953251129, -0.90398929312344, -0.88192126434836, -0.85772861000027,
                          -0.83146961230255, -0.80320753148065, -0.77301045336274, -0.74095112535496,
                          -0.70710678118655, -0.67155895484702, -0.63439328416365, -0.59569930449243,
                          -0.55557023301960, -0.51410274419322, -0.47139673682600, -0.42755509343028,
                          -0.38268343236509, -0.33688985339222, -0.29028467725447, -0.24298017990327,
                          -0.19509032201613, -0.14673047445536, -0.09801714032956, -0.04906767432742,
                          0.00000000000000
                        };

double CircleCos[257] = { 1.00000000000000, 0.99879545620517, 0.99518472667220, 0.98917650996478,
                          0.98078528040323, 0.97003125319454, 0.95694033573221, 0.94154406518302,
                          0.92387953251129, 0.90398929312344, 0.88192126434836, 0.85772861000027,
                          0.83146961230255, 0.80320753148064, 0.77301045336274, 0.74095112535496,
                          0.70710678118655, 0.67155895484702, 0.63439328416365, 0.59569930449243,
                          0.55557023301960, 0.51410274419322, 0.47139673682600, 0.42755509343028,
                          0.38268343236509, 0.33688985339222, 0.29028467725446, 0.24298017990326,
                          0.19509032201613, 0.14673047445536, 0.09801714032956, 0.04906767432742,
                          0.00000000000000, -0.04906767432742, -0.09801714032956, -0.14673047445536,
                          -0.19509032201613, -0.24298017990326, -0.29028467725446, -0.33688985339222,
                          -0.38268343236509, -0.42755509343028, -0.47139673682600, -0.51410274419322,
                          -0.55557023301960, -0.59569930449243, -0.63439328416365, -0.67155895484702,
                          -0.70710678118655, -0.74095112535496, -0.77301045336274, -0.80320753148064,
                          -0.83146961230255, -0.85772861000027, -0.88192126434835, -0.90398929312344,
                          -0.92387953251129, -0.94154406518302, -0.95694033573221, -0.97003125319454,
                          -0.98078528040323, -0.98917650996478, -0.99518472667220, -0.99879545620517,
                          -1.00000000000000, -0.99879545620517, -0.99518472667220, -0.98917650996478,
                          -0.98078528040323, -0.97003125319454, -0.95694033573221, -0.94154406518302,
                          -0.92387953251129, -0.90398929312344, -0.88192126434836, -0.85772861000027,
                          -0.83146961230255, -0.80320753148065, -0.77301045336274, -0.74095112535496,
                          -0.70710678118655, -0.67155895484702, -0.63439328416365, -0.59569930449243,
                          -0.55557023301960, -0.51410274419322, -0.47139673682600, -0.42755509343028,
                          -0.38268343236509, -0.33688985339222, -0.29028467725446, -0.24298017990326,
                          -0.19509032201613, -0.14673047445536, -0.09801714032956, -0.04906767432742,
                          0.00000000000000, 0.04906767432742, 0.09801714032956, 0.14673047445536,
                          0.19509032201613, 0.24298017990326, 0.29028467725446, 0.33688985339222,
                          0.38268343236509, 0.42755509343028, 0.47139673682600, 0.51410274419322,
                          0.55557023301960, 0.59569930449243, 0.63439328416364, 0.67155895484702,
                          0.70710678118655, 0.74095112535496, 0.77301045336274, 0.80320753148064,
                          0.83146961230254, 0.85772861000027, 0.88192126434835, 0.90398929312344,
                          0.92387953251129, 0.94154406518302, 0.95694033573221, 0.97003125319454,
                          0.98078528040323, 0.98917650996478, 0.99518472667220, 0.99879545620517,
                          1.00000000000000, 0.99879545620517, 0.99518472667220, 0.98917650996478,
                          0.98078528040323, 0.97003125319454, 0.95694033573221, 0.94154406518302,
                          0.92387953251129, 0.90398929312344, 0.88192126434836, 0.85772861000027,
                          0.83146961230255, 0.80320753148065, 0.77301045336274, 0.74095112535496,
                          0.70710678118655, 0.67155895484702, 0.63439328416365, 0.59569930449243,
                          0.55557023301960, 0.51410274419322, 0.47139673682600, 0.42755509343028,
                          0.38268343236509, 0.33688985339222, 0.29028467725446, 0.24298017990327,
                          0.19509032201613, 0.14673047445536, 0.09801714032956, 0.04906767432742,
                          0.00000000000000, -0.04906767432742, -0.09801714032956, -0.14673047445536,
                          -0.19509032201613, -0.24298017990326, -0.29028467725446, -0.33688985339222,
                          -0.38268343236509, -0.42755509343028, -0.47139673682600, -0.51410274419322,
                          -0.55557023301960, -0.59569930449243, -0.63439328416364, -0.67155895484702,
                          -0.70710678118655, -0.74095112535496, -0.77301045336274, -0.80320753148064,
                          -0.83146961230254, -0.85772861000027, -0.88192126434835, -0.90398929312344,
                          -0.92387953251129, -0.94154406518302, -0.95694033573221, -0.97003125319454,
                          -0.98078528040323, -0.98917650996478, -0.99518472667220, -0.99879545620517,
                          -1.00000000000000, -0.99879545620517, -0.99518472667220, -0.98917650996478,
                          -0.98078528040323, -0.97003125319454, -0.95694033573221, -0.94154406518302,
                          -0.92387953251129, -0.90398929312344, -0.88192126434836, -0.85772861000027,
                          -0.83146961230255, -0.80320753148065, -0.77301045336274, -0.74095112535496,
                          -0.70710678118655, -0.67155895484702, -0.63439328416365, -0.59569930449243,
                          -0.55557023301960, -0.51410274419322, -0.47139673682600, -0.42755509343028,
                          -0.38268343236509, -0.33688985339222, -0.29028467725446, -0.24298017990327,
                          -0.19509032201613, -0.14673047445536, -0.09801714032956, -0.04906767432742,
                          0.00000000000000, 0.04906767432742, 0.09801714032956, 0.14673047445536,
                          0.19509032201613, 0.24298017990326, 0.29028467725446, 0.33688985339222,
                          0.38268343236509, 0.42755509343028, 0.47139673682600, 0.51410274419322,
                          0.55557023301960, 0.59569930449243, 0.63439328416364, 0.67155895484702,
                          0.70710678118655, 0.74095112535496, 0.77301045336274, 0.80320753148064,
                          0.83146961230254, 0.85772861000027, 0.88192126434835, 0.90398929312344,
                          0.92387953251129, 0.94154406518302, 0.95694033573221, 0.97003125319454,
                          0.98078528040323, 0.98917650996478, 0.99518472667220, 0.99879545620517,
                          1.00000000000000
                        };

uint8 SwappedBitsInByte[256] =
{	0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
	0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
	0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
	0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
	0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
	0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
	0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
	0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
	0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
	0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
	0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
	0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
	0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
	0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
	0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
	0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};


extern int64 CurrentFrequency;

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double LimitRotation(double rotation)
{
	while (rotation < 0.0)
		rotation += 360.0;

	while (rotation > 360.0)
		rotation -= 360.0;

	return rotation;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double PixelToReal(int32 X)
{
	double hulp;

	hulp = X;
	return (hulp / Factor);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double PixelToRealOffX(int32 X)
{
	double hulp;

	hulp = (X - DrawWindowMinX);
	return ((hulp / Factor) + Xoffset);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double PixelToRealOffY(int32 Y)
{
	double hulp;

	hulp = Y;
	return ((hulp / Factor) + Yoffset);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void AdjustMouseToGrid(int32 MouseX, int32 MouseY, double *x2, double *y2)
{
	double hulp3, niks, f;

	hulp3 = (PixelToRealOffX(MouseX)) / GridSize;

	if (hulp3 >= 0.0)
		hulp3 += 0.5;
	else
		hulp3 -= 0.5;

	niks = modf(hulp3, &f);
	hulp3 = (f * GridSize);
	*x2 = hulp3;

	hulp3 = (PixelToRealOffY(DrawWindowMaxY - MouseY - 1)) / GridSize;

	if (hulp3 >= 0.0)
		hulp3 += 0.5;
	else
		hulp3 -= 0.5;

	niks = modf(hulp3, &f);
	hulp3 = (f * GridSize);
	*y2 = hulp3;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double AdjustToDrawGrid(double x)
{
	double hulp, niks, f;

	hulp = x / GridSize;

	if (hulp >= 0.0)
		hulp += 0.5;
	else
		hulp -= 0.5;

	niks = modf(hulp, &f);
	return (f * GridSize);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double AdjustToGrid(double x, double Grid)
{
	double hulp, niks, f;

	hulp = x / Grid;

	if (hulp >= 0.0)
		hulp += 0.5;
	else
		hulp -= 0.5;

	niks = modf(hulp, &f);
	return (f * Grid);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double AdjustToDrawGridDiv2(double x)
{
	double hulp, niks, f;

	hulp = (2 * x) / GridSize;

	if (hulp >= 0.0)
		hulp += 0.5;
	else
		hulp -= 0.5;

	niks = modf(hulp, &f);
	return (f * GridSize / 2);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void XchangeMem(uint8 * buf1, uint8 * buf2, int32 Length)
{
	uint8 Xbuf[1024], val;
	int32 cnt;

	if (Length <= 1024)
	{
		memmove(&Xbuf, buf1, Length);
		memmove(buf1, buf2, Length);
		memmove(buf2, &Xbuf, Length);
	}
	else
	{
		cnt = 0;

		while (cnt < Length)
		{
			val = *buf2;
			*(buf2++) = *buf1;
			*(buf1++) = val;
			cnt++;
		}
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double UnitsConvert(int32 Units, double value)
{
	switch (Units)
	{
	case UNITS_MILS:
		value *= 2540.0;
		break;

	case UNITS_MM:
		value *= 100000.0;
		break;

	case UNITS_INCH:
		value *= 2540000.0;
		break;

	case UNITS_0_01MM:
		value *= 1000.0;
		break;

	case UNITS_HPGL:
		value *= 2500.0;
		break;

	case UNITS_0_1MILS:
		value *= 254.0;
		break;

	case UNITS_0_1MM:
		value *= 10000.0;
		break;

	case UNITS_MICRON:
		value *= 100.0;
		break;
	}

	return value;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double ConvertToUnits(int32 Units, double value)
{
	switch (Units)
	{
	case UNITS_MILS:
		value /= 2540.0;
		break;

	case UNITS_MM:
		value /= 100000.0;
		break;

	case UNITS_INCH:
		value /= 2540000.0;
		break;

	case UNITS_0_01MM:
		value /= 1000.0;
		break;

	case UNITS_HPGL:
		value /= 2500.0;
		break;

	case UNITS_0_1MILS:
		value /= 254.0;
		break;

	case UNITS_0_1MM:
		value /= 10000.0;
		break;

	case UNITS_MICRON:
		value /= 100.0;
		break;
	}

	return value;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double ConvertToUnits2(int32 Units, double value, int32 mode)
{
	switch (Units)
	{
	case UNITS_MILS:
		value /= 2540.0;

		if (mode == 1)
		{
		}

		break;

	case UNITS_MM:
		value /= 100000.0;
		break;

	case UNITS_INCH:
		value /= 2540000.0;
		break;

	case UNITS_0_01MM:
		value /= 1000.0;
		break;

	case UNITS_HPGL:
		value /= 2500.0;
		break;

	case UNITS_0_1MILS:
		value /= 254.0;
		break;

	case UNITS_0_1MM:
		value /= 10000.0;
		break;

	case UNITS_MICRON:
		value /= 100.0;
		break;
	}

	return value;
}


// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

int32 GetUnitsValue(int32 Units, double value, LPSTR str, int32 mode)
{
	double NewValue;
	NewValue = ConvertToUnits(Units, value);

	if ((mode & 1) == 0)
		NewValue *= 1.000000001;
	else
		NewValue *= 1.0000000001;

	switch (Units)
	{
	case UNITS_MILS:
		if ((mode & 4) == 0)
		{
			if ((mode & 1) == 0)
				sprintf(str, "%.2f", NewValue);
			else
				sprintf(str, "%.4f", NewValue);

			StripAppendingZeros(str, 0);

			if ((mode & 2) == 2)
				strcat(str, " thou");
		}
		else
		{
			NewValue = ConvertToUnits(UNITS_INCH, value);
			NewValue *= 1.000000001;

			if ((mode & 1) == 0)
				sprintf(str, "%.5f", NewValue);
			else
				sprintf(str, "%.8f", NewValue);

			if ((mode & 2) == 2)
				strcat(str, SC(146, " inch"));
		}

		break;

	case UNITS_MM:
		if ((mode & 1) == 0)
			sprintf(str, "%.4f", NewValue);
		else
		{
			if ((mode & 8) == 0)
				sprintf(str, "%.7f", NewValue);
			else
				sprintf(str, "%.11f", NewValue);
		}

		StripAppendingZeros(str, 0);

		if ((mode & 2) == 2)
			strcat(str, " mm");

		break;

	case UNITS_INCH:
		if ((mode & 1) == 0)
			sprintf(str, "%.5f", NewValue);
		else
		{
			if ((mode & 8) == 0)
				sprintf(str, "%.8f", NewValue);
			else
				sprintf(str, "%.12f", NewValue);
		}

		StripAppendingZeros(str, 0);

		if ((mode & 2) == 2)
			strcat(str, SC(146, " inch"));

		break;

	case UNITS_HPGL:
		if ((mode & 1) == 0)
			sprintf(str, "%.2f", NewValue);
		else
			sprintf(str, "%.5f", NewValue);

		break;

	case UNITS_0_01MM:
		if ((mode & 1) == 0)
			sprintf(str, "%.2f", NewValue);
		else
			sprintf(str, "%.5f", NewValue);

		break;

	case UNITS_0_1MILS:
		if ((mode & 1) == 0)
			sprintf(str, "%.1f", NewValue);
		else
			sprintf(str, "%.4f", NewValue);

		break;

	case UNITS_0_1MM:
		if ((mode & 1) == 0)
			sprintf(str, "%.3f", NewValue);
		else
			sprintf(str, "%.6f", NewValue);

		break;

	case UNITS_MICRON:
		if ((mode & 1) == 0)
			sprintf(str, "%.1f", NewValue);
		else
			sprintf(str, "%.4f", NewValue);

		if ((mode & 2) == 2)
			strcat(str, " µm");

		break;
	}

	return 0;
}

// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

int32 GetUnitsValue2(int32 Units, double value, LPSTR str, int32 mode)
{
	double NewValue;
	NewValue = ConvertToUnits(Units, value);
	NewValue *= 1.000000001;

	switch (Units)
	{
	case UNITS_MILS:
		sprintf(str, "%.2f", NewValue);
		StripAppendingZeros(str, 0);

		if ((mode & 2) == 2)
			strcat(str, " thou");

		break;

	case UNITS_MM:
		sprintf(str, "%.4f", NewValue);
		StripAppendingZeros(str, 0);

		if ((mode & 2) == 2)
			strcat(str, " mm");

		break;

	case UNITS_INCH:
		sprintf(str, "%.6f", NewValue);
		StripAppendingZeros(str, 0);

		if ((mode & 2) == 2)
			strcat(str, SC(146, " inch"));

		break;

	case UNITS_MICRON:
		sprintf(str, "%.1f", NewValue);
		StripAppendingZeros(str, 0);

		if ((mode & 2) == 2)
			strcat(str, " µm");

		break;
	}

	return 0;
}


// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

int32 GetUnitText(int32 Units, LPSTR str, int32 mode)
{
	switch (Units)
	{
	case UNITS_MILS:
		strcpy(str, "thou");
		break;

	case UNITS_MM:
		strcpy(str, "mm");
		break;

	case UNITS_INCH:
		strcpy(str, SC(817, "inch"));
		break;

	case UNITS_HPGL:
		strcpy(str, "HPGL");
		break;

	case UNITS_0_01MM:
		strcpy(str, "0.01 mm");
		break;

	case UNITS_0_1MILS:
		strcpy(str, "0.1 thou");
		break;

	case UNITS_0_1MM:
		strcpy(str, "0.1 mm");
		break;

	case UNITS_MICRON:
		strcpy(str, "µm");
		break;
	}

	return 0;
}

// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

int32 SetNextUnits(int32 Units, int32 mode)
{
	if ((mode & 16) == 0)
		Units++;

	/*
	#define UNITS_MILS         0
	#define UNITS_MM           1
	#define UNITS_INCH         2
	#define UNITS_0_01MM       3
	#define UNITS_HPGL         4
	#define UNITS_0_1MILS      5
	#define UNITS_0_1MM        6
	#define UNITS_MICRON       7
	*/
	switch (mode & 15)
	{
	case 0:					// thou/mm/inch
		if (Units >= UNITS_0_01MM)
			Units = UNITS_MILS;

		break;

	case 1:					// thou/mm
		if (Units >= UNITS_INCH)
			Units = UNITS_MILS;

		break;

	case 2:					// thou/mm/inch/0.01mm/0.1thou
		if (Units == UNITS_HPGL)
			Units = UNITS_0_1MILS;

		if (Units == UNITS_0_1MM)
			Units = UNITS_MILS;

		if (Units == UNITS_MICRON)
			Units = UNITS_MILS;

		break;

	case 3:					// thou/mm/µm
		if (Units == UNITS_INCH)
			Units = UNITS_MICRON;

		if (Units == UNITS_0_01MM)
			Units = UNITS_MICRON;

		if (Units == UNITS_HPGL)
			Units = UNITS_MICRON;

		if (Units == UNITS_0_1MILS)
			Units = UNITS_MICRON;

		if (Units == UNITS_0_1MM)
			Units = UNITS_MICRON;

		break;

	case 4:					// thou/mm/inch/0.01mm
		if (Units == UNITS_HPGL)
			Units = UNITS_MILS;

		if (Units == UNITS_0_1MILS)
			Units = UNITS_MILS;

		if (Units == UNITS_0_1MM)
			Units = UNITS_MILS;

		break;

	case 5:					// thou/mm/inch/0.01mm/0.1mm
		if (Units == UNITS_HPGL)
			Units = UNITS_0_1MM;

		if (Units == UNITS_0_1MILS)
			Units = UNITS_0_1MM;

		if (Units == UNITS_MICRON)
			Units = UNITS_MILS;

		break;

	case 6:					// mm/inch
		if (Units > UNITS_INCH)
			Units = UNITS_MM;
		else
		{
			if (Units == UNITS_MILS)
				Units = UNITS_MM;
		}

		break;
	}

	if (Units == 8)
		Units = UNITS_MILS;

	if (Units < 0)
		Units = UNITS_MILS;

	return Units;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 ScanParameters(int32 NrParameters, LPSTR Str, int32 mode)
{
	int32 cnt, cnt2, pos[256], count, le, res, TempUnits, PointCount, CommaCount, PuntCommaCount;
	char SubStr[80];
	int32 FoundUnits;

	ParametersRelative = 0;
	TempUnits = -1;
	count = 0;
	le = strlen(Str);

	if (le == 0)
		return -1;

	PointCount = 0;
	CommaCount = 0;
	PuntCommaCount = 0;

	for (cnt = 0; cnt < le; cnt++)
	{
		if (Str[cnt] == '.')
			PointCount++;

		if (Str[cnt] == '.')
			CommaCount++;

		if (Str[cnt] == ';')
			PuntCommaCount++;
	}

	if (Str[0] == '@')
	{
		ParametersRelative = 1;
		memmove(&Str[0], &Str[1], le - 1);
		le--;

		if (le == 0)
			return -1;
	}
	else
	if (Str[0] == '#')
	{
		ParametersRelative = 0;
		memmove(&Str[0], &Str[1], le - 1);
		le--;

		if (le == 0)
			return -1;
	}

	pos[0] = -1;

	for (cnt = 0; cnt < le; cnt++)
	{
		if (Str[cnt] == ',')
		{
			pos[count + 1] = cnt;
			count++;
		}
	}

	pos[count + 1] = cnt;
	count++;

	if ((NrParameters != -1) && (count != NrParameters))
		return -2;

	for (cnt = 0; cnt < count; cnt++)
	{
		memset(&SubStr, 0, sizeof(SubStr));
		memmove(&SubStr, &Str[pos[cnt] + 1], pos[cnt + 1] - pos[cnt] - 1);
		le = strlen((LPSTR) & SubStr);
		FoundUnits = 0;
		cnt2 = le - 1;

		while ((cnt2 >= 0) && (SubStr[cnt2] == ' '))
		{
			SubStr[cnt2] = 0;
			cnt2--;
		}

		le = strlen((LPSTR) & SubStr);
		cnt2 = 0;

		while ((cnt2 < le) && (SubStr[cnt2] == ' '))
			cnt2++;

		if (mode == 0)
		{
			res = sscanf((LPSTR) & SubStr[cnt2], "%f", &ParamsFloat[cnt]);

			if (res == 0)
				return -3;

			_strlwr((LPSTR) & SubStr);
			le = strlen((LPSTR) & SubStr);

			if (le > 2)
			{
				if ((SubStr[le - 1] == 'm') && (SubStr[le - 2] == 'm'))
					TempUnits = 1;

				if ((SubStr[le - 1] == 'h') && (SubStr[le - 2] == 't'))
					TempUnits = 0;
			}

			if (le > 3)
			{
				if ((SubStr[le - 1] == 'l') && (SubStr[le - 2] == 'i') && (SubStr[le - 2] == 'm'))
					TempUnits = 0;
			}

			if (le > 4)
			{
				if ((SubStr[le - 1] == 's') && (SubStr[le - 2] == 'l') && (SubStr[le - 3] == 'i')
				        && (SubStr[le - 4] == 'm'))
					TempUnits = 0;

				if ((SubStr[le - 1] == 'h') && (SubStr[le - 2] == 'c') && (SubStr[le - 3] == 'n')
				        && (SubStr[le - 4] == 'i'))
					TempUnits = 2;
			}
		}
	}
	
	if (mode == 0)
	{
		for (cnt = 0; cnt < count; cnt++)
		{
			if (TempUnits == -1)
			{
				switch (Units)
				{
				case 0:
					ParamsFloat[cnt] *= 2540.0;
					break;

				case 1:
					ParamsFloat[cnt] *= 100000.0;
					break;
				}
			}
			else
			{
				switch (TempUnits)
				{
				case 0:
					ParamsFloat[cnt] *= 2540.0;
					break;

				case 1:
					ParamsFloat[cnt] *= 100000.0;
					break;

				case 2:
					ParamsFloat[cnt] *= 2540000.0;
					break;
				}
			}
		}
	}

	return count;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void RotateFlipPoint(float *x, float *y, double OX, double OY, int32 Mode)
{
	double hx, hy;

	switch (Mode)
	{
	case 1:					// 45
		RotatePointFromOtherPoint(x, y, OX, OY, 45.0);
		break;

	case 2:					// 90
		hx = OX + OY - *y;
		hy = -OX + OY + *x;
		*x = (float) hx;
		*y = (float) hy;
		break;

	case 3:					// 135
		RotatePointFromOtherPoint(x, y, OX, OY, 135.0);
		break;

	case 4:					// 180
		hx = 2 * OX - *x;
		hy = 2 * OY - *y;
		*x = (float) hx;
		*y = (float) hy;
		break;

	case 5:					// 225
		RotatePointFromOtherPoint(x, y, OX, OY, 225.0);
		break;

	case 6:					// 270
		hx = OX - OY + *y;
		hy = OX + OY - *x;
		*x = (float) hx;
		*y = (float) hy;
		break;

	case 7:					// 315
		RotatePointFromOtherPoint(x, y, OX, OY, 315.0);
		break;
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void RotateFlipPoint2(double *x, double *y, double OX, double OY, int32 Mode)
{
	double hx, hy;

	switch (Mode)
	{
	case 1:					// 45
		RotatePointFromOtherPoint2(x, y, OX, OY, 45.0);
		break;

	case 2:					// 90
		hx = OX + OY - *y;
		hy = -OX + OY + *x;
		*x = hx;
		*y = hy;
		break;

	case 3:					// 135
		RotatePointFromOtherPoint2(x, y, OX, OY, 135.0);
		break;

	case 4:					// 180
		hx = 2 * OX - *x;
		hy = 2 * OY - *y;
		*x = hx;
		*y = hy;
		break;

	case 5:					// 225
		RotatePointFromOtherPoint2(x, y, OX, OY, 225.0);
		break;

	case 6:					// 270
		hx = OX - OY + *y;
		hy = OX + OY - *x;
		*x = hx;
		*y = hy;
		break;

	case 7:					// 315
		RotatePointFromOtherPoint2(x, y, OX, OY, 315.0);
		break;
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void RotatePoint(float *x, float *y, double Rotation)
{
	double hx, hy, dx, dy, r1, length, hoek;

	if (InRange11(Rotation, 0.0))
		return;
	else if (InRange11(Rotation, ANGLE_90))
	{
		hx = -*y;
		hy = *x;
		*x = (float) hx;
		*y = (float) hy;
		return;
	}
	else if (InRange11(Rotation, ANGLE_180))
	{
		*x = -*x;
		*y = -*y;
		return;
	}
	else if (InRange11(Rotation, ANGLE_270))
	{
		hx = *y;
		hy = -*x;
		*x = (float) hx;
		*y = (float) hy;
		return;
	}
	else
	{
		dx = *x;
		dy = *y;

		if (InRange11(dx, 0.0))
		{
			if (dy > 0.0)
				hoek = ANGLE_90;
			else
				hoek = ANGLE_270;
		}
		else
		{
			r1 = dy / dx;
			hoek = atan(r1);

			if (r1 > 0.0)
			{
				if (dx < 0.0)
					hoek += ANGLE_180;
			}
			else
			{
				if (dx > 0.0)
					hoek += ANGLE_360;
				else
					hoek += ANGLE_180;
			}
		}

		hoek += ANGLE_CONVERT(Rotation);
		length = sqrt(SQR(dx) + SQR(dy));

		if (InRange11(hoek, 0.0))
		{
			*x = (float) length;
			*y = 0.0;
		}
		else if (InRange11(hoek, ANGLE_90))
		{
			*x = 0.0;
			*y = (float) length;
		}
		else if (InRange11(hoek, ANGLE_180))
		{
			*x = (float) -length;
			*y = 0.0;
		}
		else if (InRange11(hoek, ANGLE_270))
		{
			*x = 0.0;
			*y = (float) -length;
		}
		else
		{
			*x = (float) (cos(hoek) * length);
			*y = (float) (sin(hoek) * length);
		}
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void RotatePoint2(double *x, double *y, double Rotation)
{
	double hx, hy, dx, dy, r1, length, hoek;

	if (InRange11(Rotation, 0.0))
		return;
	else if (InRange11(Rotation, ANGLE_90))
	{
		hx = -*y;
		hy = *x;
		*x = (float) hx;
		*y = (float) hy;
		return;
	}
	else if (InRange11(Rotation, ANGLE_180))
	{
		*x = -*x;
		*y = -*y;
		return;
	}
	else if (InRange11(Rotation, ANGLE_270))
	{
		hx = *y;
		hy = -*x;
		*x = (float) hx;
		*y = (float) hy;
		return;
	}
	else
	{
		dx = *x;
		dy = *y;

		if (InRange11(dx, 0.0))
		{
			if (dy > 0.0)
				hoek = ANGLE_90;
			else
				hoek = ANGLE_270;
		}
		else
		{
			r1 = dy / dx;
			hoek = atan(r1);

			if (r1 > 0.0)
			{
				if (dx < 0.0)
					hoek += ANGLE_180;
			}
			else
			{
				if (dx > 0.0)
					hoek += ANGLE_360;
				else
					hoek += ANGLE_180;
			}
		}

		hoek += ANGLE_CONVERT(Rotation);
		length = sqrt(SQR(dx) + SQR(dy));

		if (InRange11(hoek, 0.0))
		{
			*x = (float) length;
			*y = 0.0;
		}
		else if (InRange11(hoek, ANGLE_90))
		{
			*x = 0.0;
			*y = (float) length;
		}
		else if (InRange11(hoek, ANGLE_180))
		{
			*x = (float) -length;
			*y = 0.0;
		}
		else if (InRange11(hoek, ANGLE_270))
		{
			*x = 0.0;
			*y = (float) -length;
		}
		else
		{
			*x = (float) (cos(hoek) * length);
			*y = (float) (sin(hoek) * length);
		}
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void RotatePointFromOtherPoint(float *x, float *y, double OX, double OY, double Rotation)
{
	double dx, dy, r1, length, hoek;

	if (InRange2(Rotation, 0.0))
		return;

	dx = *x - OX;
	dy = *y - OY;
	length = sqrt(SQR(dx) + SQR(dy));

	if (dx == 0.0)
	{	// Vertical line
		if (dy > 0.0)
		{	// Vertical line to top
			hoek = ANGLE_90;
		}
		else
		{	// Vertical line to bottom
			hoek = ANGLE_270;
		}
	}
	else
	{
		r1 = dy / dx;
		hoek = atan(r1);

		if (r1 > 0.0)
		{
			if (dx < 0.0)
				hoek += ANGLE_180;
		}
		else
		{
			if (dx > 0.0)
				hoek += ANGLE_360;
			else
				hoek += ANGLE_180;
		}
	}

	hoek += ANGLE_CONVERT(Rotation);

	if (hoek > ANGLE_360)
		hoek -= ANGLE_360;

	if (InRange11(hoek, 0.0))
	{
		*x = (float) length;
		*y = 0.0;
	}
	else if (InRange11(hoek, ANGLE_90))
	{
		*x = 0.0;
		*y = (float) length;
	}
	else if (InRange11(hoek, ANGLE_180))
	{
		*x = (float) -length;
		*y = 0.0;
	}
	else if (InRange11(hoek, ANGLE_270))
	{
		*x = 0.0;
		*y = (float) -length;
	}
	else
	{
		*x = (float) (cos(hoek) * length);
		*y = (float) (sin(hoek) * length);
	}

	*x += (float) OX;
	*y += (float) OY;
}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void ConvertPointToPolar(double x, double y, double *Distance, double *Angle)
{
	double r1, length, hoek;

	length = sqrt(SQR(x) + SQR(y));
	*Distance = length;

	if (x == 0.0)
	{	// Vertical line
		if (y > 0.0)
		{	// Vertical line to top
			hoek = ANGLE_90;
		}
		else
		{	// Vertical line to bottom
			hoek = ANGLE_270;
		}
	}
	else
	{
		r1 = y / x;
		hoek = atan(r1);

		if (r1 > 0.0)
		{
			if (x < 0.0)
				hoek += ANGLE_180;
		}
		else
		{
			if (x > 0.0)
				hoek += ANGLE_360;
			else
				hoek += ANGLE_180;
		}
	}

	if (hoek > ANGLE_360 - 0.001)
		hoek -= ANGLE_360;

	*Angle = (hoek * 180.0 / PI);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void ConvNormalCoorToPolar(double x1, double y1, double x2, double y2, double *Angle, double *Length)
{
	double dx, dy, r1, hoek;

	dx = x2 - x1;
	dy = y2 - y1;

	if ((dx == 0.0) && (dy == 0.0))
	{
		*Length = 0.0;
		*Angle = 0.0;
		return;
	}

	*Length = sqrt(SQR(dx) + SQR(dy));

	if (InRangeSpecial(dx, 0.0, 0.00001))
	{	// Vertical line
		if (dy > 0.0)
		{	// Vertical line to top
			hoek = ANGLE_90;
		}
		else
		{	// Vertical line to bottom
			hoek = ANGLE_270;
		}
	}
	else
	{
		r1 = dy / dx;
		hoek = atan(r1);

		if (r1 >= 0.0)
		{
			if (dx < 0.0)
				hoek += ANGLE_180;
		}
		else
		{
			if (dx > 0.0)
				hoek += ANGLE_360;
			else
			{
				if (dx < 0.0)
					hoek += ANGLE_180;
			}
		}
	}

	*Angle = hoek;
}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void RotatePointFromOtherPoint2(double *x, double *y, double OX, double OY, double Rotation)
{
	double dx, dy, r1, length, hoek;

	if (InRange2(Rotation, 0.0))
		return;


	dx = *x - OX;
	dy = *y - OY;
	length = sqrt(SQR(dx) + SQR(dy));

	if (dx == 0.0)
	{	// Vertical line
		if (dy > 0.0)
		{	// Vertical line to top
			hoek = ANGLE_90;
		}
		else
		{	// Vertical line to bottom
			hoek = ANGLE_270;
		}
	}
	else
	{
		r1 = dy / dx;
		hoek = atan(r1);

		if (r1 > 0.0)
		{
			if (dx < 0.0)
				hoek += ANGLE_180;
		}
		else
		{
			if (dx > 0.0)
				hoek += ANGLE_360;
			else
				hoek += ANGLE_180;
		}
	}

	hoek += ANGLE_CONVERT(Rotation);

	if (hoek > ANGLE_360)
		hoek -= ANGLE_360;

	if (InRangeSpecial(hoek, 0.0, 0.0001))
	{
		*x = length;
		*y = 0.0;
	}
	else if (InRangeSpecial(hoek, ANGLE_90, 0.0001))
	{
		*x = 0.0;
		*y = length;
	}
	else if (InRangeSpecial(hoek, ANGLE_180, 0.0001))
	{
		*x = -length;
		*y = 0.0;
	}
	else if (InRangeSpecial(hoek, ANGLE_270, 0.0001))
	{
		*x = 0.0;
		*y = -length;
	}
	else
	{
		*x = cos(hoek) * length;
		*y = sin(hoek) * length;
	}

	*x += OX;
	*y += OY;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 RectTestLine2(double LineX1, double LineY1, double LineX2, double LineY2)
{
	double LineXmin, LineXmax, LineYmin, LineYmax, DifX, DifY, xa, xb, ya, yb;
	double rico, rico2;

	LineXmin = LineX1;
	LineYmin = LineY1;
	LineXmax = LineX2;
	LineYmax = LineY2;

	if (LineXmin > LineXmax)
	{
		LineXmin = LineX2;
		LineXmax = LineX1;
	}

	if (LineYmin > LineYmax)
	{
		LineYmin = LineY2;
		LineYmax = LineY1;
	}

	if ((X1SmallerThenX2(LineXmax, SearchMinX)) || (X1GreaterThenX2(LineXmin, SearchMaxX))
	        || (X1SmallerThenX2(LineYmax, SearchMinY)) || (X1GreaterThenX2(LineYmin, SearchMaxY)))
		return 0;


	if ((X1SmallerThenX2(LineXmax, SearchMaxX)) && (X1GreaterThenX2(LineXmin, SearchMinX))
	        && (X1SmallerThenX2(LineYmax, SearchMaxY)) && (X1GreaterThenX2(LineYmin, SearchMinY)))
		return 3;


	if ((X1SmallerThenX2(LineX1, SearchMaxX)) && (X1GreaterThenX2(LineX1, SearchMinX))
	        && (X1SmallerThenX2(LineY1, SearchMaxY)) && (X1GreaterThenX2(LineY1, SearchMinY)))
		return 1;

	if ((X1SmallerThenX2(LineX2, SearchMaxX)) && (X1GreaterThenX2(LineX2, SearchMinX))
	        && (X1SmallerThenX2(LineY2, SearchMaxY)) && (X1GreaterThenX2(LineY2, SearchMinY)))
		return 2;

	if ((InRange(LineX1, LineX2)) || (InRange(LineY1, LineY2)))
		return 3;

	DifX = LineX2 - LineX1;
	DifY = LineY2 - LineY1;
	rico = LineY2;
	rico = (rico - LineY1) / (LineX2 - LineX1);
	ya = ((SearchMinX - LineX1) * rico) + LineY1;
	yb = ((SearchMaxX - LineX1) * rico) + LineY1;

	if (((ya > SearchMinY) && (ya < SearchMaxY)) || ((yb > SearchMinY) && (yb < SearchMaxY)))
		return 3;

	rico2 = LineX2;
	rico2 = (rico2 - LineX1) / (LineY2 - LineY1);
	xa = ((SearchMinY - LineY1) * rico2) + LineX1;
	xb = ((SearchMaxY - LineY1) * rico2) + LineX1;

	if (((xa > SearchMinX) && (xa < SearchMaxX)) || ((xb > SearchMinX) && (xb < SearchMaxX)))
		return 3;

	return 0;

	/*

	Line with two points (x1,y1) and (x2,y2)


	y=ax+b

	           (y2-y1)
	y = (x-x1)*------- + y1
	           (x2-x1)

	           (x2-x1)
	x = (y-y1)*------- + x1
	           (y2-y1)



	y = x-x1 + y1

	x = y-y1 + x1

	*/

}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 RectTestLine3(double LineX1, double LineY1, double LineX2, double LineY2, double Thickness)
{
	double LineXmin, LineXmax, LineYmin, LineYmax, DifX, DifY, xa, xb, ya, yb, rico, rico2;

	LineXmin = LineX1 - Thickness;
	LineYmin = LineY1 - Thickness;
	LineXmax = LineX2 + Thickness;
	LineYmax = LineY2 + Thickness;

	if (LineXmin > LineXmax)
	{
		LineXmin = LineX2 - Thickness;
		LineXmax = LineX1 + Thickness;
	}

	if (LineYmin > LineYmax)
	{
		LineYmin = LineY2 - Thickness;
		LineYmax = LineY1 + Thickness;
	}

	if ((X1SmallerThenX2(LineXmax, SearchMinX)) || (X1GreaterThenX2(LineXmin, SearchMaxX))
	        || (X1SmallerThenX2(LineYmax, SearchMinY)) || (X1GreaterThenX2(LineYmin, SearchMaxY)))
		return 0;


	if ((X1SmallerThenX2(LineXmax, SearchMaxX)) && (X1GreaterThenX2(LineXmin, SearchMinX))
	        && (X1SmallerThenX2(LineYmax, SearchMaxY)) && (X1GreaterThenX2(LineYmin, SearchMinY)))
		return 3;


	if ((X1SmallerThenX2(LineX1, SearchMaxX)) && (X1GreaterThenX2(LineX1, SearchMinX))
	        && (X1SmallerThenX2(LineY1, SearchMaxY)) && (X1GreaterThenX2(LineY1, SearchMinY)))
		return 1;

	if ((X1SmallerThenX2(LineX2, SearchMaxX)) && (X1GreaterThenX2(LineX2, SearchMinX))
	        && (X1SmallerThenX2(LineY2, SearchMaxY)) && (X1GreaterThenX2(LineY2, SearchMinY)))
		return 2;

	if ((InRange(LineX1, LineX2)) || (InRange(LineY1, LineY2)))
		return 3;

	DifX = LineX2 - LineX1;
	DifY = LineY2 - LineY1;
	rico = LineY2;
	rico = (rico - LineY1) / (LineX2 - LineX1);
	ya = ((SearchMinX - LineX1) * rico) + LineY1;
	yb = ((SearchMaxX - LineX1) * rico) + LineY1;

	if (((ya > SearchMinY - Thickness) && (ya < SearchMaxY + Thickness))
	        || ((yb > SearchMinY - Thickness) && (yb < SearchMaxY + Thickness)))
		return 3;

	rico2 = LineX2;
	rico2 = (rico2 - LineX1) / (LineY2 - LineY1);
	xa = ((SearchMinY - LineY1) * rico2) + LineX1;
	xb = ((SearchMaxY - LineY1) * rico2) + LineX1;

	if (((xa > SearchMinX - Thickness) && (xa < SearchMaxX + Thickness))
	        || ((xb > SearchMinX - Thickness) && (xb < SearchMaxX + Thickness)))
		return 3;

	return 0;

	/*

	Line with two points (x1,y1) and (x2,y2)


	y=ax+b

	           (y2-y1)
	y = (x-x1)*------- + y1
	           (x2-x1)

	           (x2-x1)
	x = (y-y1)*------- + x1
	           (y2-y1)



	y = x-x1 + y1

	x = y-y1 + x1

	*/

}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 GetRotationFromFloat(double Rotation)
{
	double rot, diff;
	int32 NewRotation;

	if (Rotation < 0)
		Rotation += 360;

	diff = modf((Rotation + 0.001) / 45.0, &rot);

	if (diff < 0.00003)
	{
		NewRotation = (int32) rot;

		if ((NewRotation & 1) == 0)
		{	// 90 degrees increments
			return (NewRotation >> 1);
		}
		else
			return ((NewRotation >> 1) + 4);
	}

	return -1;
}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void SevereProgramError(LPSTR SourceFile, int32 LineNr)
{
#ifdef _DEBUG
	
	int32 ok;
	ok = 1;
#else
	char MessageStr[MAX_LENGTH_STRING];
	sprintf(MessageStr, "Severe error in %s :  Line : %d", SourceFile, LineNr);
	MessageBoxOwn(NULL, MessageStr, SC(24, "Error"), MB_APPLMODAL | MB_OK);
#endif
}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CircleTestCircleObjects(double CircleX1, double CircleY1, double CircleThickness1, double CircleX2,
                              double CircleY2, double CircleThickness2)
{
	double hulpx, hulpy, hulp;

	hulpx = (CircleX1 - CircleX2);
	hulpy = (CircleY1 - CircleY2);
	hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

	if (hulp <= ((CircleThickness1 + CircleThickness2) * 0.5))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 RectTestCircleObjects(double RectX, double RectY, double RectWidth, double RectHeight, double CircleX,
                            double CircleY, double CircleThickness)
{
	double CircleXmin, CircleXmax, CircleYmin, CircleYmax, RectXmin, RectXmax, RectYmin, RectYmax, xa, ya, r, rxmin,
	       rymin, rxmax, rymax;

	CircleThickness = CircleThickness * 0.5;
	RectWidth = RectWidth * 0.5;
	RectHeight = RectHeight * 0.5;

	CircleXmin = CircleX - CircleThickness;
	CircleYmin = CircleY - CircleThickness;
	CircleXmax = CircleX + CircleThickness;
	CircleYmax = CircleY + CircleThickness;

	RectXmin = RectX - RectWidth;
	RectYmin = RectY - RectHeight;
	RectXmax = RectX + RectWidth;
	RectYmax = RectY + RectHeight;

	if ((CircleXmax < RectXmin) || (CircleXmin > RectXmax) || (CircleYmax < RectYmin) || (CircleYmin > RectYmax))
		return 0;

	if ((CircleXmax <= RectXmax) && (CircleXmin >= RectXmin) && (CircleYmax <= RectYmax) && (CircleYmin >= RectYmin))
		return 1;

	r = CircleThickness;
	r = r * r;

	rxmin = RectXmin - CircleX;
	rxmin = rxmin * rxmin;
	rxmax = RectXmax - CircleX;
	rxmax = rxmax * rxmax;
	rymin = RectYmin - CircleY;
	rymin = rymin * rymin;
	rymax = RectYmax - CircleY;
	rymax = rymax * rymax;

	if (rxmin + rymin <= r)
		return 1;

	if (rxmin + rymax <= r)
		return 1;

	if (rxmax + rymin <= r)
		return 1;

	if (rxmax + rymax <= r)
		return 1;

//  RectTestCircleOutline(x1,y1,x2,255);
	r = CircleThickness;
	r = r * r;
	rxmin = RectXmin - CircleX;
	rxmin = r - rxmin * rxmin;
	rxmax = RectXmax - CircleX;
	rxmax = r - rxmax * rxmax;

	if (rxmin >= 0)
	{
		ya = sqrt(rxmin);

		if (((CircleY - ya >= RectYmin) && (CircleY - ya <= RectYmax))
		        || ((CircleY + ya >= RectYmin) && (CircleY + ya <= RectYmax)))
			return 1;
	}

	if (rxmax >= 0)
	{
		ya = sqrt(rxmax);

		if (((CircleY - ya >= RectYmin) && (CircleY - ya <= RectYmax))
		        || ((CircleY + ya >= RectYmin) && (CircleY + ya <= RectYmax)))
			return 1;
	}

	rymin = RectYmin - CircleY;
	rymin = r - rymin * rymin;
	rymax = RectYmax - CircleY;
	rymax = r - rymax * rymax;

	if (rymin >= 0)
	{
		xa = sqrt(rymin);

		if (((CircleX - xa >= RectXmin) && (CircleX - xa <= RectXmax))
		        || ((CircleX + xa >= RectXmin) && (CircleX + xa <= RectXmax)))
			return 1;
	}

	if (rymax >= 0)
	{
		xa = sqrt(rymax);

		if (((CircleX - xa >= RectXmin) && (CircleX - xa <= RectXmax))
		        || ((CircleX + xa >= RectXmin) && (CircleX + xa <= RectXmax)))
			return 1;
	}

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CircleTestDiag1Objects(double CircleX, double CircleY, double CircleThickness, double Diag1X1, double Diag1Y1,
                             double Diag1LengthX, double Diag1Width)
{

	/*            1
	             /\
	           /   \
	         / xd1  \
	     4 /         \
	       \          \
	        \          \
	         \          \
	          \          \
	           \          \
	            \         /  2
	             \      /
	              \   / xd2
	               \/
	               3
	*/


	double Diag1X2, Diag1Y2, xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4, r, CircleR, CircleMinXD, CircleMinYD, CircleMaxXD,
	       CircleMaxYD, hulpx, hulpy, hulp;

	Diag1X2 = Diag1X1 + Diag1LengthX;
	Diag1Y2 = Diag1Y1 - Diag1LengthX;

	hulp = Diag1Width;
	hulp = hulp * SQRT05 * 0.5;
	r = hulp;

	hulp = CircleThickness;
	hulp = hulp * SQRT05 * 0.5;
	CircleR = hulp;

	CircleMinXD = CircleX - CircleR;
	CircleMinYD = CircleY - CircleR;
	CircleMaxXD = CircleX + CircleR;
	CircleMaxYD = CircleY + CircleR;

	xx4 = Diag1X1 - r;
	yy4 = Diag1Y1 - r;
	xx2 = Diag1X2 + r;
	yy2 = Diag1Y2 + r;

	if (CircleMaxXD + CircleMaxYD < xx4 + yy4)
		return 0;

	if (CircleMinXD + CircleMinYD > xx2 + yy2)
		return 0;

	if (-CircleMaxXD + CircleMinYD > -xx4 + yy4)
		return 0;

	if (-CircleMinXD + CircleMaxYD < -xx2 + yy2)
		return 0;

	if ((-CircleMinXD + CircleMaxYD <= -xx4 + yy4) && (-CircleMaxXD + CircleMinYD >= -xx2 + yy2)
	        && (CircleMinXD + CircleMinYD <= xx2 + yy2) && (CircleMaxXD + CircleMaxYD >= xx4 + yy4))
		return 1;

	xx1 = Diag1X1 + r;
	yy1 = Diag1Y1 + r;

	xx3 = Diag1X2 - r;
	yy3 = Diag1Y2 - r;

	if ((CircleX + CircleY > xx2 + yy2) && (-CircleX + CircleY > -xx4 + yy4))
	{
		hulpx = CircleX - xx1;
		hulpy = CircleY - yy1;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}


	if ((-CircleX + CircleY < -xx2 + yy2) && (CircleX + CircleY < xx4 + yy4))
	{
		hulpx = CircleX - xx3;
		hulpy = CircleY - yy3;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}

	if ((CircleX + CircleY < xx4 + yy4) && (-CircleX + CircleY > -xx4 + yy4))
	{
		hulpx = CircleX - xx4;
		hulpy = CircleY - yy4;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}


	if ((-CircleX + CircleY < -xx2 + yy2) && (CircleX + CircleY > xx2 + yy2))
	{
		hulpx = CircleX - xx2;
		hulpy = CircleY - yy2;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}

	return 1;

}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CircleTestDiag2Objects(double CircleX, double CircleY, double CircleThickness, double Diag2X1, double Diag2Y1,
                             double Diag2LengthX, double Diag2Width)
{

	/*                 1

	                 / \
	               /    \
	             /       *  x2
	           /          \
	         /             \
	       /              /  2
	 4   /              /
	   /              /
	   \            /
	    \         /
	     *      /
	  x1  \   /
	       \/
	         3
	*/
	double Diag2X2, Diag2Y2, xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4, r, hulp, hulpx, hulpy, CircleR, CircleMinXD,
	       CircleMinYD, CircleMaxXD, CircleMaxYD;

	Diag2X2 = Diag2X1 + Diag2LengthX;
	Diag2Y2 = Diag2Y1 + Diag2LengthX;

	hulp = Diag2Width;
	hulp = hulp * SQRT05 * 0.5;
	r = hulp;

	hulp = CircleThickness;
	hulp = hulp * SQRT05 * 0.5;
	CircleR = hulp;

	CircleMinXD = CircleX - CircleR;
	CircleMinYD = CircleY - CircleR;
	CircleMaxXD = CircleX + CircleR;
	CircleMaxYD = CircleY + CircleR;

	xx4 = Diag2X1 - r;
	yy4 = Diag2Y1 + r;
	xx2 = Diag2X2 + r;
	yy2 = Diag2Y2 - r;

	if (CircleMaxXD + CircleMaxYD < xx4 + yy4)
		return 0;

	if (CircleMinXD + CircleMinYD > xx2 + yy2)
		return 0;

	if (-CircleMaxXD + CircleMinYD > -xx4 + yy4)
		return 0;

	if (-CircleMinXD + CircleMaxYD < -xx2 + yy2)
		return 0;

	if ((-CircleMinXD + CircleMaxYD <= -xx4 + yy4) && (-CircleMaxXD + CircleMinYD >= -xx2 + yy2)
	        && (CircleMinXD + CircleMinYD <= xx2 + yy2) && (CircleMaxXD + CircleMaxYD >= xx4 + yy4))
		return 1;

	xx1 = Diag2X1 - r;
	yy1 = Diag2Y1 + r;

	xx3 = Diag2X2 + r;
	yy3 = Diag2Y2 - r;

	if ((CircleX + CircleY > xx2 + yy2) && (-CircleX + CircleY > -xx4 + yy4))
	{
		hulpx = CircleX - xx1;
		hulpy = CircleY - yy1;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}


	if ((-CircleX + CircleY < -xx2 + yy2) && (CircleX + CircleY < xx4 + yy4))
	{
		hulpx = CircleX - xx3;
		hulpy = CircleY - yy3;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}

	if ((CircleX + CircleY < xx4 + yy4) && (-CircleX + CircleY > -xx4 + yy4))
	{
		hulpx = CircleX - xx4;
		hulpy = CircleY - yy4;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}


	if ((-CircleX + CircleY < -xx2 + yy2) && (CircleX + CircleY > xx2 + yy2))
	{
		hulpx = CircleX - xx2;
		hulpy = CircleY - yy2;
		hulp = sqrt(hulpx * hulpx + hulpy * hulpy);

		if (hulp > CircleThickness * 0.5)
			return 0;
	}

	return 1;


}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 RectTestDiag1Objects(double RectX, double RectY, double RectWidth, double RectHeight, double Diag1X1,
                           double Diag1Y1, double Diag1LengthX, double Diag1Width)
{

	/*            1               +---------------------+
	             /\               |                     |
	           /   \              |                     |
	         / x1   \             |                     |
	     4 /         \            |                     |
	       \          \           |                     |
	        \          \          +---------------------+
	         \          \
	          \          \
	           \          \
	            \         /  2
	             \      /
	              \   / x2
	               \/
	               3
	*/


	double Diag1X2, Diag1Y2, xx2, yy2, xx4, yy4, r, RectMinX, RectMinY, RectMaxX, RectMaxY, Diag1MinX, Diag1MaxX,
	       Diag1MinY, Diag1MaxY, hulp;

	Diag1X2 = Diag1X1 + Diag1LengthX;
	Diag1Y2 = Diag1Y1 - Diag1LengthX;

	hulp = Diag1Width;
	hulp = hulp * SQRT05 * 0.5;
	r = hulp;

	Diag1MinX = Diag1X1 - r;
	Diag1MinY = Diag1Y2 - r;
	Diag1MaxX = Diag1X2 + r;
	Diag1MaxY = Diag1Y1 + r;

	RectMinX = RectX - RectWidth * 0.5;
	RectMinY = RectY - RectHeight * 0.5;
	RectMaxX = RectX + RectWidth * 0.5;
	RectMaxY = RectY + RectHeight * 0.5;

	if ((Diag1MaxX < RectMinX) || (Diag1MinX > RectMaxX) || (Diag1MaxY < RectMinY) || (Diag1MinY > RectMaxY))
		return 0;

	xx4 = Diag1X1 - r;
	yy4 = Diag1Y1 - r;
	xx2 = Diag1X2 + r;
	yy2 = Diag1Y2 + r;

	if (RectMaxX + RectMaxY < xx4 + yy4)
		return 0;

	if (RectMinX + RectMinY > xx2 + yy2)
		return 0;

	if (-RectMinX + RectMaxY < -xx2 + yy2)
		return 0;

	if (-RectMaxX + RectMinY > -xx4 + yy4)
		return 0;

	return 1;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 RectTestDiag2Objects(double RectX, double RectY, double RectWidth, double RectHeight, double Diag2X1,
                           double Diag2Y1, double Diag2LengthX, double Diag2Width)
{

	/*                 1

	                 / \
	               /    \
	             /       *  x2
	           /          \
	         /             \
	       /              /  2
	 4   /              /
	   /              /
	   \            /
	    \         /
	     *      /
	  x1  \   /
	       \/
	         3
	*/
	double Diag2X2, Diag2Y2, xx2, yy2, xx4, yy4, r, hulp, RectMinX, RectMinY, RectMaxX, RectMaxY, Diag2MinX, Diag2MaxX,
	       Diag2MinY, Diag2MaxY;

	Diag2X2 = Diag2X1 + Diag2LengthX;
	Diag2Y2 = Diag2Y1 + Diag2LengthX;

	hulp = Diag2Width;
	hulp = hulp * SQRT05 * 0.5;
	r = hulp;

	RectMinX = RectX - RectWidth * 0.5;
	RectMinY = RectY - RectHeight * 0.5;
	RectMaxX = RectX + RectWidth * 0.5;
	RectMaxY = RectY + RectHeight * 0.5;

	Diag2MinX = Diag2X1 - r;
	Diag2MaxX = Diag2X2 + r;
	Diag2MinY = Diag2Y1 - r;
	Diag2MaxY = Diag2Y2 + r;

	if ((Diag2MaxX < RectMinX) || (Diag2MinX > RectMaxX) || (Diag2MaxY < RectMinY) || (Diag2MinY > RectMaxY))
		return 0;

	xx4 = Diag2X1 - r;
	yy4 = Diag2Y1 + r;
	xx2 = Diag2X2 + r;
	yy2 = Diag2Y2 - r;

	if (-RectMaxX + RectMinY > -xx4 + yy4)
		return 0;

	if (-RectMinX + RectMaxY < -xx2 + yy2)
		return 0;

	if (RectMaxX + RectMaxY < xx4 + yy4)
		return 0;

	if (RectMinX + RectMinY > xx2 + yy2)
		return 0;

	return 1;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 Diag1TestDiag1Objects(double Diag1X11, double Diag1Y11, double Diag1LengthX1, double Diag1Width1, double Diag1X21,
                            double Diag1Y21, double Diag1LengthX2, double Diag1Width2)
{


	double Diag1X12, Diag1Y12, Diag1X22, Diag1Y22, xx12, yy12, xx14, yy14, r1, xx22, yy22, xx24, yy24, r2, hulp;

	Diag1X12 = Diag1X11 + Diag1LengthX1;
	Diag1Y12 = Diag1Y11 - Diag1LengthX1;

	Diag1X22 = Diag1X21 + Diag1LengthX2;
	Diag1Y22 = Diag1Y21 - Diag1LengthX2;

	hulp = Diag1Width1;
	hulp = hulp * SQRT05 * 0.5;
	r1 = hulp;

	hulp = Diag1Width2;
	hulp = hulp * SQRT05 * 0.5;
	r2 = hulp;

	xx14 = Diag1X11 - r1;
	yy14 = Diag1Y11 - r1;

	xx12 = Diag1X12 + r1;
	yy12 = Diag1Y12 + r1;

	xx24 = Diag1X21 - r2;
	yy24 = Diag1Y21 - r2;

	xx22 = Diag1X22 + r2;
	yy22 = Diag1Y22 + r2;

	if (xx12 + yy12 < xx24 + yy24)
		return 0;

	if (xx14 + yy14 > xx22 + yy22)
		return 0;

	if (-xx12 + yy12 > -xx24 + yy24)
		return 0;

	if (-xx14 + yy14 < -xx22 + yy22)
		return 0;

	return 1;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 Diag1TestDiag2Objects(double Diag1X11, double Diag1Y11, double Diag1LengthX1, double Diag1Width1, double Diag2X21,
                            double Diag2Y21, double Diag2LengthX2, double Diag2Width2)
{
	double Diag1X12, Diag1Y12, Diag2X22, Diag2Y22, xx12, yy12, xx14, yy14, r1, xx22, yy22, xx24, yy24, r2, hulp;

	Diag1X12 = Diag1X11 + Diag1LengthX1;
	Diag1Y12 = Diag1Y11 - Diag1LengthX1;

	Diag2X22 = Diag2X21 + Diag2LengthX2;
	Diag2Y22 = Diag2Y21 + Diag2LengthX2;

	hulp = Diag1Width1;
	hulp = hulp * SQRT05 * 0.5;
	r1 = hulp;

	hulp = Diag2Width2;
	hulp = hulp * SQRT05 * 0.5;
	r2 = hulp;

	xx14 = Diag1X11 - r1;
	yy14 = Diag1Y11 - r1;

	xx12 = Diag1X12 + r1;
	yy12 = Diag1Y12 + r1;

	xx24 = Diag2X21 - r2;
	yy24 = Diag2Y21 + r2;

	xx22 = Diag2X22 + r2;
	yy22 = Diag2Y22 - r2;

	if (xx12 + yy12 < xx24 + yy24)
		return 0;

	if (xx14 + yy14 > xx22 + yy22)
		return 0;

	if (-xx12 + yy12 > -xx24 + yy24)
		return 0;

	if (-xx14 + yy14 < -xx22 + yy22)
		return 0;

	return 1;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 Diag2TestDiag2Objects(double Diag2X11, double Diag2Y11, double Diag2LengthX1, double Diag2Width1, double Diag2X21,
                            double Diag2Y21, double Diag2LengthX2, double Diag2Width2)
{
	double Diag2X12, Diag2Y12, Diag2X22, Diag2Y22, xx12, yy12, xx14, yy14, r1, xx22, yy22, xx24, yy24, r2, hulp;

	Diag2X12 = Diag2X11 + Diag2LengthX1;
	Diag2Y12 = Diag2Y11 + Diag2LengthX1;

	Diag2X22 = Diag2X21 + Diag2LengthX2;
	Diag2Y22 = Diag2Y21 + Diag2LengthX2;

	hulp = Diag2Width1;
	hulp = hulp * SQRT05 * 0.5;
	r1 = hulp;

	hulp = Diag2Width2;
	hulp = hulp * SQRT05 * 0.5;
	r2 = hulp;

	xx14 = Diag2X11 - r1;
	yy14 = Diag2Y11 + r1;

	xx12 = Diag2X12 + r1;
	yy12 = Diag2Y12 - r1;

	xx24 = Diag2X21 - r2;
	yy24 = Diag2Y21 + r2;

	xx22 = Diag2X22 + r2;
	yy22 = Diag2Y22 - r2;

	if (xx12 + yy12 < xx24 + yy24)
		return 0;

	if (xx14 + yy14 > xx22 + yy22)
		return 0;

	if (-xx12 + yy12 > -xx24 + yy24)
		return 0;

	if (-xx14 + yy14 < -xx22 + yy22)
		return 0;

	return 1;
}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************


int32 InRangeRico(double rico1, double rico2)
{
	if (rico1 == rico2)
		return 1;

	if ((rico1 == 0) && (fabs(rico2) < 0.0001))
		return 1;

	if ((rico2 == 0) && (fabs(rico1) < 0.0001))
		return 1;

	if ((rico1 < 0) && (rico1 < rico2 * 0.99) && (rico1 > rico2 * 1.01))
		return 1;

	if ((rico1 > 0) && (rico1 > rico2 * 0.99) && (rico1 < rico2 * 1.01))
		return 1;

	if ((fabs(rico1) < 0.0001) && (fabs(rico2) < 0.0001))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double GetAngleBetweenLines(double x1, double y1, double x2, double y2, double x3, double y3)
{
	double Angle1, Angle2, Distance1, Distance2, Angle;

	ConvNormalCoorToPolar(x2, y2, x1, y1, &Angle1, &Distance1);
	ConvNormalCoorToPolar(x2, y2, x3, y3, &Angle2, &Distance2);
	Angle = fabs(Angle1 - Angle2);

	if (Angle > ANGLE_180)
		Angle -= ANGLE_180;

	return Angle;
}


// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

void GetString2a(LPSTR Str, LPSTR Result)
{
	int32 cnt, l, pos;

	Result[0] = 0;
	l = strlen(Str);

	if (l == 0)
		return;

	cnt = 0;

	while ((cnt < l) && ((Str[cnt] == ',') || (Str[cnt] == ' ') || (Str[cnt] == '\t')))
		cnt++;

	if (cnt == l)
	{
		Str[0] = 0;
		return;
	}

	if (Str[cnt] == '\"')
	{
		cnt++;
		pos = cnt;

		while ((cnt < l) && (Str[cnt] != '\"'))
			cnt++;

		if (cnt > pos)
			memmove(Result, &Str[pos], cnt - pos);

		Result[cnt - pos] = 0;
		cnt++;
	}
	else
	{
		pos = cnt;
		cnt++;

		while ((cnt < l) && (Str[cnt] != ' ') && (Str[cnt] != '\t') && (Str[cnt] != ','))
			cnt++;

		if (cnt > pos)
			memmove(Result, &Str[pos], cnt - pos);

		Result[cnt - pos] = 0;
	}

	if (cnt == l)
	{
		Str[0] = 0;
		return;
	}

	memmove(Str, &Str[cnt], l - cnt + 1);
}

// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

void GetString2b(LPSTR Str, LPSTR Delimiters, LPSTR Result)
{
	int32 cnt, cnt2, l, pos, DelimiterCount, Stop;

	Result[0] = 0;
	DelimiterCount = strlen(Delimiters);

	if (DelimiterCount == 0)
		return;

	l = strlen(Str);

	if (l == 0)
		return;

	Stop = 0;
	cnt = 0;

	while (!Stop)
	{
		if (cnt < l)
		{
			cnt2 = 0;

			while ((cnt2 < DelimiterCount) && (Str[cnt] != Delimiters[cnt2]))
				cnt2++;

			if (cnt2 < DelimiterCount)
				cnt++;
			else
				Stop = 1;
		}
		else
			Stop = 1;
	}

	if (cnt == l)
	{
		Str[0] = 0;
		return;
	}

	if (Str[cnt] == '\"')
	{
		cnt++;
		pos = cnt;

		while ((cnt < l) && (Str[cnt] != '\"'))
			cnt++;

		if (cnt > pos)
			memmove(Result, &Str[pos], cnt - pos);

		Result[cnt - pos] = 0;
		cnt++;
	}
	else
	{
		pos = cnt;
		cnt++;

		Stop = 0;

		while (!Stop)
		{
			if (cnt < l)
			{
				cnt2 = 0;

				while ((cnt2 < DelimiterCount) && (Str[cnt] != Delimiters[cnt2]))
					cnt2++;

				if (cnt2 < DelimiterCount)
					Stop = 1;
				else
					cnt++;
			}
			else
				Stop = 1;
		}

		if (cnt > pos)
			memmove(Result, &Str[pos], cnt - pos);

		Result[cnt - pos] = 0;
	}

	if (cnt == l)
	{
		Str[0] = 0;
		return;
	}

	memmove(Str, &Str[cnt], l - cnt + 1);
}



// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CompressSrcDestLayer(int32 SrcLayer, int32 DestLayer)
{
	int32 l1, l2, cnt;

	l1 = -1;

	for (cnt = 0; cnt < NrGraphicsLayers; cnt++)
	{
		if (GraphicsLayers[cnt] == SrcLayer)
			l1 = cnt;
	}

	l2 = -1;

	for (cnt = 0; cnt < NrGraphicsLayers; cnt++)
	{
		if (GraphicsLayers[cnt] == DestLayer)
			l2 = cnt;
	}

	if ((l1 != -1) && (l2 != -1))
		return (l1 << 8) + (l2);

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************


int32 DecompressSrcDestLayer(int32 CodedLayer, int32 * SrcLayer, int32 * DestLayer)
{
	*SrcLayer = GraphicsLayers[(CodedLayer >> 8) & 0xFF];
	*DestLayer = GraphicsLayers[CodedLayer & 0xFF];
	return 0;
}

// ***************************************************************************************************
// ***************************************************************************************************
// ***************************************************************************************************
// ***************************************************************************************************

void SetDialogItemText(HWND Dialog, int32 DlgItem, LPSTR Text)
{
	SendDlgItemMessageOwn(Dialog, DlgItem, WM_SETTEXT, 0, (LPARAM) Text);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************


void SendDlgItemUnits(HWND Dialog, int32 Control, int32 Units)
{
	switch (Units)
	{
	case 0:
		SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) (LPSTR) "thou");
		break;

	case 1:
		SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) (LPSTR) "mm");
		break;

	case 2:
		SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) (LPSTR) "\xc2\xb5m");
		break;
	}
}

// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************

int32 SetUnitText(HWND Dialog, int32 Control, int32 Units)
{
	char str[MAX_LENGTH_STRING];

	GetUnitText(Units, str, 0);
	SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) (LPSTR) str);
	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void SetDialogValue(HWND Dialog, int32 Control, double value)
{
	char str[MAX_LENGTH_STRING];

	if (TempUnits == 0)
		sprintf(str, "%.1f", value / 2540.0);
	else
		sprintf(str, "%.4f", value / 100000.0);

	StripAppendingZeros(str, 0);
	SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) str);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void SetDialogValue2(HWND Dialog, int32 Control, double value)
{
	char str[MAX_LENGTH_STRING];

	if (TempUnits == 0)
		sprintf(str, "%.4f", value / 2540.0);
	else
		sprintf(str, "%.7f", value / 100000.0);

	StripAppendingZeros(str, 0);
	SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) str);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void SetDialogFloatValue(HWND Dialog, int32 Control, double value, int32 Resolution)
{
	char str[MAX_LENGTH_STRING];

	switch (Resolution)
	{
	case 1:
		sprintf(str, "%.1f", value);
		break;

	case 2:
		sprintf(str, "%.2f", value);
		break;

	case 3:
		sprintf(str, "%.3f", value);
		break;

	case 4:
		sprintf(str, "%.4f", value);
		break;

	case 5:
		sprintf(str, "%.5f", value);
		break;

	case 6:
		sprintf(str, "%.6f", value);
		break;

	default:
		sprintf(str, "%.7f", value);
		break;
	}

	StripAppendingZeros(str, 0);
	SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) str);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void SetDialogIntValue(HWND Dialog, int32 Control, int32 value)
{
	char str[MAX_LENGTH_STRING];

	sprintf(str, "%d", value);
	SendDlgItemMessageOwn(Dialog, Control, WM_SETTEXT, 0, (LPARAM) str);
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

double GetDialogValue(HWND Dialog, int32 Control)
{
	char str[MAX_LENGTH_STRING];
	float value;
	double value1;

	str[0] = 0;
	value = 0.0;
	value1 = 0.0;
	SendDlgItemMessageOwn(Dialog, Control, WM_GETTEXT, MAX_LENGTH_STRING - 1, (LPARAM) str);

	if (sscanf(str, "%f", &value) == 1)
	{
		value1 = atof(str);

		if (TempUnits == 0)
			value1 *= 2540.0;
		else
			value1 *= 100000.0;
	}

	return value1;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 GetDialogIntValue(HWND Dialog, int32 Control, int32 * Value)
{
	char str[MAX_LENGTH_STRING];
	int32 NewValue;

	str[0] = 0;
	SendDlgItemMessageOwn(Dialog, Control, WM_GETTEXT, MAX_LENGTH_STRING - 1, (LPARAM) str);

	if (sscanf(str, "%d", &NewValue) == 1)
	{
		*Value = NewValue;
		return 1;
	}

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 GetDialogFloatValue(HWND Dialog, int32 Control, double *Value)
{
	char str[MAX_LENGTH_STRING];
	float NewValue;

	str[0] = 0;
	SendDlgItemMessageOwn(Dialog, Control, WM_GETTEXT, MAX_LENGTH_STRING - 1, (LPARAM) str);

	if (sscanf(str, "%f", &NewValue) == 1)
	{
		*Value = NewValue;
		return 1;
	}

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckIfInnerLayer(int32 Layer)
{
	if ((Design.NrBoardLayers > 2) && (Layer > 0) && (Layer != Design.NrBoardLayers - 1))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckIfTopLayer(int32 Layer)
{
	if ((Design.NrBoardLayers > 1) && (Layer == Design.NrBoardLayers - 1))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckIfBottomLayer(int32 Layer)
{
	if (Layer == 0)
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckIfCopperLayer(int32 Layer)
{
	if (Layer < 0)
		return 0;

	if ((Layer < 32) || ((Layer >= ROUTING_KEEPOUT_LAYER) && (Layer < ROUTING_KEEPOUT_LAYER + 32)))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckIfDrillLayer(int32 Layer)
{
	if ((Layer == DRILL_LAYER) || (Layer == DRILL_UNPLATED_LAYER))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckIfLayerHasObjectWithClearances(int32 Layer)
{
	if (Layer < 0)
		return 0;

	if ((Layer < 32) || (Layer == DRILL_LAYER) || (Layer == DRILL_UNPLATED_LAYER))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 CheckGeometryLayer(int32 * Layer, int32 NrGeomLayers, int32 Mirror)
{
	if ((*Layer >= 32) || (*Layer < -1))
	{
		*Layer = 0;
		return 0;
	}

	if (*Layer == -1)
		return 1;

// *******************************************************************************************************
	if (NrGeomLayers <= 2)
	{
		if (Mirror == 0)
		{
			if (Design.NrBoardLayers == 1)
			{
				if (*Layer >= 1)
					return 0;

				*Layer = 0;
			}
			else
			{
				if (*Layer >= 1)
					*Layer = Design.NrBoardLayers - 1;
				else
					*Layer = 0;
			}
		}
		else
		{
			if (Design.NrBoardLayers == 1)
			{
				if (*Layer == 0)
					return 0;

				*Layer = 0;
			}
			else
			{
				if (*Layer == 0)
					*Layer = Design.NrBoardLayers - 1;
				else
					*Layer = 0;
			}
		}

		return 1;
	}

// *******************************************************************************************************
// Nr geometry layers > 2
	if (Design.NrBoardLayers == 1)
	{
		if (Mirror == 0)
		{
			if (*Layer > 0)
				return 0;
		}
		else
		{
			if (*Layer < NrGeomLayers - 1)
				return 0;
		}

		*Layer = 0;
		return 1;
	}

// *******************************************************************************************************
	if (Design.NrBoardLayers == 2)
	{
		if ((*Layer > 0) && (*Layer < NrGeomLayers - 1))
		{	// Objects on inner geometry layers will not be used
			return 0;
		}

		if (Mirror == 0)
		{
			if (*Layer > 0)
				*Layer = 1;
			else
				*Layer = 0;
		}
		else
		{
			if (*Layer == 0)
				*Layer = 1;
			else
				*Layer = 0;
		}

		return 1;
	}

// *******************************************************************************************************
// Nr geometry layers > 2
// Nr board layers > 2

	if (NrGeomLayers < Design.NrBoardLayers)
	{
		if (*Layer == NrGeomLayers - 1)
		{	// Top layer in the geometrie
			*Layer = Design.NrBoardLayers - 1;
		}
	}

	if (NrGeomLayers > Design.NrBoardLayers)
	{
		if (*Layer == NrGeomLayers - 1)
		{	// Top layer in the geometrie
			*Layer = Design.NrBoardLayers - 1;
		}
	}

	if (Mirror == 1)
		*Layer = Design.NrBoardLayers - 1 - *Layer;

	if (*Layer >= Design.NrBoardLayers)
		*Layer = Design.NrBoardLayers - 1;

	return 1;
}



// ******************************************************************************************************************************
// ******************************************************************************************************************************
// ******************************************************************************************************************************
// ******************************************************************************************************************************

ObjectRecord *GetNewObject4()
{
	ObjectRecord *Object4;

	if (NrObjects4 + 1 > MaxNrObjects4)
	{
		if (AllocateMemObjects4(MaxNrObjects4 + 2048) == -1)
			return NULL;
	}

	Object4 = &((*Objects4)[NrObjects4]);
	memset(Object4, 0, sizeof(ObjectRecord));
	return Object4;
}

// ******************************************************************************************************************************
// ******************************************************************************************************************************
// ******************************************************************************************************************************
// ******************************************************************************************************************************

ObjectRecord *GetNewObject5(int32 Layer)
{
	ObjectRecord *Object5;

	if (NrObjects5 + 1 > MaxNrObjects5)
	{
		if (AllocateMemObjects5(MaxNrObjects5 + 2048) == -1)
			return NULL;
	}

	Object5 = &((*Objects5)[NrObjects5]);
	memset(Object5, 0, sizeof(ObjectRecord));
	Object5->Layer = (Layer << 24) + NrLayerPlotObjects[Layer];
	Object5->NetNr = -1;
	NrLayerPlotObjects[Layer]++;
	NrObjects5++;
	return Object5;
}

// ******************************************************************************************************************************
// ******************************************************************************************************************************
// ******************************************************************************************************************************
// ******************************************************************************************************************************

#if 0
ObjectRecord *GetNewLayerPlotObject(int32 Layer)
{
	ObjectRecord *Object;

	if (NrLayerPlotObjects[Layer] + 1 > MaxLayerPlotObjects[Layer])
	{
		if (AllocateSpecialMem(MEM_LAYER_OBJECTS + Layer, MaxLayerPlotObjects[Layer] + 2048, &LayerPlotObjects[Layer])
		        == -1)
			return NULL;

		MaxLayerPlotObjects[Layer] += 2048
	}

	Object = &((*LayerPlotObjects[Layer])[NrLayerPlotObjects[Layer]]);
	memset(Object, 0, sizeof(ObjectRecord));
	return Object;
}
#endif

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 IsRoutingKeepoutLayer(int32 Layer)
{
	if ((Layer >= ROUTING_KEEPOUT_LAYER) && (Layer < ROUTING_KEEPOUT_LAYER + 32))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

uint8 SwapBitsByte(uint8 code)
{
	int32 cnt, ok;
	uint8 result = 0;
	uint8 BitCode = 0x80;

	if ((code != 0) && (code != 255))
		ok = 1;

	for (cnt = 0; cnt < 8; cnt++)
	{
		if ((code & (1 << cnt)) != 0)
			result |= BitCode;

		BitCode >>= 1;
	}

	return result;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************


void SwapBitsLine(uint8 * LineBytes, int32 ByteCount)
{
	int32 cnt, cnt2;
	uint8 value1, value2;

	for (cnt = 0; cnt < ByteCount / 2; cnt++)
	{
		cnt2 = ByteCount - cnt - 1;
		value1 = SwappedBitsInByte[LineBytes[cnt]];
		value2 = SwappedBitsInByte[LineBytes[cnt2]];
		LineBytes[cnt] = value2;
		LineBytes[cnt2] = value1;
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

void GetRotationAndMirrorFromShapeText(double ShapeRotation, double *Rotation, int32 * Mirror)
{
	int32 rot;

	if (ShapeRotation > 10.0)
	{
		// Floating point number
		ShapeRotation -= 2000.0;

		if (ShapeRotation > 1000.0)
		{
			// Mirrored text
			*Rotation = ShapeRotation - 2000.0;
			*Mirror = 1;
		}
		else
		{
			*Rotation = ShapeRotation;
			*Mirror = 0;
		}
	}
	else
	{
		rot = (int32) (ShapeRotation + 0.1);
		rot = ((rot & 3) << 1) + ((rot & 4) >> 2);
		*Rotation = rot * 45;
		*Mirror = 0;
	}
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 IsPolygonVisible(PolygonRecord * DrawPolygon, int32 mode)
{
	if ((DrawPolygon->maxx >= ViewMinX) && (DrawPolygon->minx <= ViewMaxX) && (DrawPolygon->maxy >= ViewMinY)
	        && (DrawPolygon->miny <= ViewMaxY))
		return 1;

	return 0;
}


// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 IsAreaFillVisible(AreaFillRecord * AreaFill, int32 mode)
{
	if ((AreaFill->maxx >= ViewMinX) && (AreaFill->minx <= ViewMaxX) && (AreaFill->maxy >= ViewMinY)
	        && (AreaFill->miny <= ViewMaxY))
		return 1;

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 AdjustOffsetOnPoints(double *Points, double OffsetX, double OffsetY, int32 count, int32 mode)
{
	int32 cnt;

	for (cnt = 0; cnt < count; cnt++)
	{
		*Points += OffsetX;
		Points++;
		*Points += OffsetY;
		Points++;
	}

	return 0;
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

int32 ConvertTextString(LPSTR TextStr, LPSTR NewTextStr, int32 Layer)
{
	struct tm FileTime, *today;
	time_t ltime;
	char NewStr[MAX_LENGTH_STRING], str2[MAX_LENGTH_STRING];
	int32 cnt, Length;

	Length = strlen(TextStr);

	if ((Length < 2) || (TextStr[0] != '$'))
	{
//    strcpy(NewTextStr,TextStr);
		return -1;
	}

	strcpy(NewStr, TextStr);
	cnt = 2;

	while (__iscsym(NewStr[cnt]))
		cnt++;

	NewStr[cnt] = 0;

	if (stricmp(NewStr, "$DATE") == 0)
	{
		if (Design.DesignDate.Year != 0)
		{
			FileTime.tm_year = Design.DesignDate.Year;
			FileTime.tm_mon = Design.DesignDate.Month - 1;
			FileTime.tm_mday = Design.DesignDate.Day;
			FileTime.tm_hour = Design.DesignDate.Hour;
			FileTime.tm_min = Design.DesignDate.Minutes;
			FileTime.tm_sec = 0;
			strftime(ConvertedTextString, 100, "%B %d, %Y    %X", &FileTime);
		}
		else
		{
			time(&ltime);
			today = localtime(&ltime);
			strftime(ConvertedTextString, 100, "%B %d, %Y    %X", today);
		}

		strcpy(NewTextStr, ConvertedTextString);
		return 0;
	}

	if (stricmp(NewStr, "$DESIGNNAME") == 0)
	{
		GetFilePartFromFileName(str2, EditFile);
		CutExtensionFileName(str2);
		strcpy(NewTextStr, str2);
		return 0;
	}

	if (stricmp(NewStr, "$LAYER") == 0)
	{
		GetLayerTextObjects(Layer, NewTextStr, 16 + 4);
		return 0;
	}

	if (GetUserVar(NewStr, ConvertedTextString, 0) == 1)
	{
		strcpy(NewTextStr, ConvertedTextString);
		return 0;
	}

	strcpy(NewTextStr, NewStr);
	return 0;
}

/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/

uint32 mktime2(uint32 year, uint32 mon, uint32 day, uint32 hour, uint32 min, uint32 sec)
{
//  year-=1900;
//  mon--;
	if (0 >= (int) (mon -= 2))
	{	/* 1..12 -> 11,12,1..10 */
		mon += 12;				/* Puts Feb last since it has leap day */
		year -= 1;
	}

	return ((((uint32) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + year * 365 - 719499) * 24 + hour	/* now have hours */
	        ) * 60 + min		/* now have minutes */
	       ) * 60 + sec;			/* finally seconds */
}

// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************
// *******************************************************************************************************

/*
SYSTEMTIME                  CurrentDateProgramStart;
int64                       SpecialCounterProgramStart;
*/

int32 GetTimeString(int32 mode, LPSTR TimeString)
{
//  SYSTEMTIME CurrentDate;
	int64 SpecialCounter, hulp;
	int32 micro_seconds;
	uint32 hour, min, sec, temp_seconds;
	/*
	  NrSecondsAfter1970=mktime2(CurrentDate.wYear,CurrentDate.wMonth,CurrentDate.wDay,
	                             CurrentDate.wHour,CurrentDate.wMinute,CurrentDate.wSecond);
	*/
	QueryPerformanceCounter((LARGE_INTEGER *) & SpecialCounter);
	hulp = (SpecialCounter - SpecialCounterProgramStart) * 1000000;
	hulp /= CurrentFrequency;


	temp_seconds = CurrentDateProgramStart.wHour * 3600;
	temp_seconds += CurrentDateProgramStart.wMinute * 60;
	temp_seconds += CurrentDateProgramStart.wSecond;
	temp_seconds += (int32) (hulp / 1000000);
	hour = temp_seconds / 3600;
	temp_seconds %= 3600;
	min = temp_seconds / 60;
	temp_seconds %= 60;
	sec = temp_seconds;
	micro_seconds = (int32) (hulp % 1000000);

	switch (mode)
	{
	case 0:
		sprintf(TimeString, "%02d:%02d:%02d.%06d", hour, min, sec, micro_seconds);
		break;

	case 1:
		sprintf(TimeString, "%02d-%02d-%4d %02d:%02d:%02d.%06d", CurrentDateProgramStart.wDay,
		        CurrentDateProgramStart.wMonth, CurrentDateProgramStart.wYear, hour, min, sec, micro_seconds);
		break;
	}
	
	return 0;
}

// ********************************************************************************************************
// ********************************************************************************************************
// ********************************************************************************************************
// ********************************************************************************************************
